﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using Telerik.WinControls.UI;
using Zvezda.FSO2.DB;
using Zvezda.FSO2.DB.DataSetFSOTableAdapters;
namespace FSO
{
    public partial class FormCostProtocol : Form, InterfaceObjDeleteableForm
    {
        DataSetFSO.COST_PROTOCOLRow _costPRow;
		public bool AllowSave;
        public FormCostProtocol(int? pid)
        {
            InitializeComponent();
            if (pid == null)
            {

            }
            else
            {
                _costPRow = dataSetFSO1.COST_PROTOCOL.NewCOST_PROTOCOLRow();
                dataSetFSO1.COST_PROTOCOL.AddCOST_PROTOCOLRow(_costPRow);
                _costPRow.PID = pid.Value;
                _costPRow.START_DATE = DateTime.Now.Date;
                _costPRow.END_DATE = DateTime.Now.Date.AddDays(30);
                _costPRow.IS_AGREED = false;
            }
        }

        public FormCostProtocol(DataSetFSO.COST_PROTOCOLRow row)
        {
            InitializeComponent();

            cosT_PROTOCOLTableAdapter1.FillByID(dataSetFSO1.COST_PROTOCOL, row.ID);
            _costPRow = dataSetFSO1.COST_PROTOCOL.FindByID(row.ID);

            this.Text = "Протокол № " + _costPRow.NUMBER;
        }

        private void InitializeProductUnitsGrid()
        {
            //radGridViewItems.ReadOnly = true;

            GridViewTextBoxColumn colItemName = new GridViewTextBoxColumn("PRODUCT_NAME", dataSetFSO1.AGGR_PRODUCT_COST.NAMEColumn.ColumnName);
            colItemName.HeaderText = "Наименование";
            colItemName.ReadOnly = true;

            GridViewDecimalColumn colItemCount = new GridViewDecimalColumn("COUNT", dataSetFSO1.AGGR_PRODUCT_COST.COUNTColumn.ColumnName);
            colItemCount.HeaderText = "Кол.";
            colItemCount.Minimum = 1;
            //colItemCount.ReadOnly = true;
            //colItemCount.Maximum = 100; //Пересчитываемая функция (зависит от количества товаров в КП)

            GridViewTextBoxColumn colMeter = new GridViewTextBoxColumn("METER_NAME", dataSetFSO1.AGGR_PRODUCT_COST.NSI_METER_NAMEColumn.ColumnName);
            colMeter.HeaderText = "Ед.";
            colMeter.ReadOnly = true;

            GridViewDecimalColumn colCost = new GridViewDecimalColumn("COST", dataSetFSO1.AGGR_PRODUCT_COST.COSTColumn.ColumnName);
            colCost.HeaderText = "Цена за ед. (с НДС)";
            colCost.Minimum = 0;
            colCost.FormatString = "{0:N2} " + radDropDownListNsiCurrency.SelectedText;

            GridViewTextBoxColumn colCPSTNum = new GridViewTextBoxColumn("CP_STAGE_NUM", dataSetFSO1.AGGR_PRODUCT_COST.CP_STAGE_NUMColumn.ColumnName);
            colCPSTNum.HeaderText = "План\\№ Этап";
            colCPSTNum.ReadOnly = true;

            GridViewTextBoxColumn colCPSTName = new GridViewTextBoxColumn("CP_STAGE_NAME", dataSetFSO1.AGGR_PRODUCT_COST.CP_STAGE_NAMEColumn.ColumnName);
            colCPSTName.HeaderText = "Этап";
            colCPSTName.ReadOnly = true;

            GridViewDateTimeColumn colCPSDate = new GridViewDateTimeColumn("CP_STAGE_SDATE", dataSetFSO1.AGGR_PRODUCT_COST.CP_STAGE_SDATEColumn.ColumnName);
            colCPSDate.HeaderText = "С";
            colCPSDate.FormatString = "{0:d}";
            colCPSDate.ReadOnly = true;

            GridViewDateTimeColumn colCPEDate = new GridViewDateTimeColumn("CP_STAGE_EDATE", dataSetFSO1.AGGR_PRODUCT_COST.CP_STAGE_EDATEColumn.ColumnName);
            colCPEDate.HeaderText = "По";
            colCPEDate.FormatString = "{0:d}";
            colCPEDate.ReadOnly = true;


            radGridViewItems.MasterTemplate.Columns.Clear();
            radGridViewItems.MasterTemplate.Columns.Add(colItemName);
            radGridViewItems.MasterTemplate.Columns.Add(colCost);
            radGridViewItems.MasterTemplate.Columns.Add(colItemCount);
            radGridViewItems.MasterTemplate.Columns.Add(colMeter);
            radGridViewItems.MasterTemplate.Columns.Add(colCPSTNum);
            //radGridViewItems.MasterTemplate.Columns.Add(colCPSTName);
            radGridViewItems.MasterTemplate.Columns.Add(colCPSDate);
            radGridViewItems.MasterTemplate.Columns.Add(colCPEDate);

            radGridViewItems.MasterTemplate.SummaryRowGroupHeaders.Clear();
            radGridViewItems.GroupDescriptors.Clear();
            GridViewSummaryRowItem summaryString = new GridViewSummaryRowItem();
            GridViewSummaryItem itemCount = new GridViewSummaryItem("COUNT", "Кол. - {0}", GridAggregateFunction.Sum);
            GridViewSummaryItem avgCost = new GridViewSummaryItem("COST", "Средняя цена - {0:N2}", GridAggregateFunction.Avg);
            summaryString.Add(itemCount);
            summaryString.Add(avgCost);
            radGridViewItems.MasterTemplate.SummaryRowGroupHeaders.Add(summaryString);
            //GridAggregateFunction f = new GridAggregateFunction();
            

            radGridViewItems.DataSource = dataSetFSO1.AGGR_PRODUCT_COST;

        }

        private void BindControls()
        {
            //Номер протокола
            radTextBoxNumber.DataBindings.Clear();
            radTextBoxNumber.DataBindings.Add("Text", _costPRow, dataSetFSO1.COST_PROTOCOL.NUMBERColumn.ColumnName, true, DataSourceUpdateMode.OnPropertyChanged);

            //Начало и конец действия
            radDateTimePickerStartDate.DataBindings.Clear();
            radDateTimePickerStartDate.DataBindings.Add("Value", _costPRow, dataSetFSO1.COST_PROTOCOL.START_DATEColumn.ColumnName, true, DataSourceUpdateMode.OnPropertyChanged);
            radDateTimePickerEndDate.DataBindings.Clear();
            radDateTimePickerEndDate.DataBindings.Add("Value", _costPRow, dataSetFSO1.COST_PROTOCOL.END_DATEColumn.ColumnName, true, DataSourceUpdateMode.OnPropertyChanged);
            
            //Валюта
            radDropDownListNsiCurrency.DataBindings.Clear();
            radDropDownListNsiCurrency.DataBindings.Add("SelectedValue", _costPRow, dataSetFSO1.COST_PROTOCOL.NSI_CURRENCY_IDColumn.ColumnName, true, DataSourceUpdateMode.OnPropertyChanged);

            //Согласованность
            radCheckBoxIsAgree.DataBindings.Clear();
            radCheckBoxIsAgree.DataBindings.Add("Checked", _costPRow, dataSetFSO1.COST_PROTOCOL.IS_AGREEDColumn.ColumnName, true, DataSourceUpdateMode.OnPropertyChanged);
        }

        private void EnabledControls(bool isEnable)
        {
            radTextBoxNumber.ReadOnly = !isEnable;
            radDateTimePickerEndDate.Enabled = isEnable;
            radDateTimePickerStartDate.Enabled = isEnable;
            radDropDownListNsiCurrency.Enabled = isEnable;
            radButtonAdd.Enabled = isEnable;
            radButtonDelete.Enabled = isEnable;
            radGridViewItems.ReadOnly = !isEnable;
        }

        public int Delete()
        {
            bool isCanDelete = true;
            if (_costPRow.IS_AGREED)
            {
                isCanDelete = false;
                //MessageBox.Show(this, "Протокол согласован! Удаление невозможно", "Соглавсованный протокол", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else if(_costPRow.RowState != DataRowState.Added)
            {
                //Проверяем на все агрегированные строки цен, если есть хоть одна с ненулевым количеством товаров, то нельзя удалить протокол
                foreach (DataSetFSO.AGGR_PRODUCT_COSTRow row in dataSetFSO1.AGGR_PRODUCT_COST.Rows)
                {
                    if (row.COUNT > 0)
                    {
                        isCanDelete = false;
                        break;
                    }
                    //Проверяем все единицы продукции, если есть хоть 1 связь, то нельзя удвлить протокол
                    else
                    {
                        VIEW_SEARCH_P_U_FOR_FORMSTableAdapter ta = new VIEW_SEARCH_P_U_FOR_FORMSTableAdapter();
                        DataSetFSO.VIEW_SEARCH_P_U_FOR_FORMSRow prUnitRow;
                        foreach (DataSetFSO.PRODUCT_COSTRow tmpCostPrRow in (producT_COSTTableAdapter1.GetDataForCostPrByProductsNameCPStage(row.CP_STAGE_ID, _costPRow.PID, _costPRow.ID, row.NAME)).Rows)
                        {
                            prUnitRow = ta.GetDataByPrUnitID(tmpCostPrRow.PRODUCT_UNIT_ID).FindByID(tmpCostPrRow.PRODUCT_UNIT_ID);
                        
                            if (!(prUnitRow.IsPAYMENT_IN_SUM_CURNull() && prUnitRow.IsPAYMENT_IN_SUM_RUBNull() && prUnitRow.IsINVOICE_IN_SUMNull() && prUnitRow.IsVAT_INVOICE_IDNull() && prUnitRow.IsDIRECT_NUMBER_IDNull() && prUnitRow.IsGUILD_BILL_NUMBER_IDNull()))
                            {
                                isCanDelete = false;
                                break;
                            }
                        }
                    }
                }
            }

            if (isCanDelete)
            {
                _costPRow.Delete();
                cosT_PROTOCOLTableAdapter1.Update(_costPRow);
                this.Close();
            }
            else
            {
                MessageBox.Show("Невозможно удалить протокол!", "Удаление", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return 0;
        }

        public int Save()
        {
            int returnValue = 0;

            if (_costPRow.IsNUMBERNull() || _costPRow.IsNSI_CURRENCY_IDNull())
            {
                MessageBox.Show(this, "Не заполнено обязательное поле \"Номер\" или \"Валюта\".\nИзменения не будут сохранены", "Обязательное поле", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return -1;
            }

            //Заполняем реальную таблицу цен
            producT_COSTTableAdapter1.FillByCostPrID(dataSetFSO1.PRODUCT_COST, _costPRow.ID);

            //количество товаров которое нельзя удалить из протокола
            int notDelCount = 0;
            foreach (DataSetFSO.AGGR_PRODUCT_COSTRow row in dataSetFSO1.AGGR_PRODUCT_COST.Rows)
            {

                //Проверем на нулевую цену
                if (row.COUNT != 0 && (row.IsCOSTNull() || row.COST == 0))
                {
                    MessageBox.Show(this, "Есть цены с нулевым значением! Сохранение невозможно!", "Нулевая цена", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return -1;
                }

                //dCount - переменная показывающая изменение количества продаваемоей продукции одного наименования
                int dCount = 0;
                int curCount = row.COUNT;
                decimal cost = row.COST;
                bool isModified = false;
                if (row.RowState == DataRowState.Added)
                {
                    dCount = row.COUNT;
                }
                if (row.RowState == DataRowState.Modified)
                {
                    //row.RejectChanges();
                    dCount = curCount - (int) row[dataSetFSO1.AGGR_PRODUCT_COST.COUNTColumn, DataRowVersion.Original];
                    isModified = true;
                }

                if (dCount > 0)
                {
                    //Заполняем таблицу товаров свободными от цены продуктами в количестве dCount штук
                    producT_UNITTableAdapter1.FillForCostPrAddUnits(dataSetFSO1.PRODUCT_UNIT, dCount, _costPRow.PID, row.CP_STAGE_ID, row.NAME);

                    foreach (DataSetFSO.PRODUCT_UNITRow unitsRow in dataSetFSO1.PRODUCT_UNIT.Rows)
                    {
                        DataSetFSO.PRODUCT_COSTRow productCostRow = dataSetFSO1.PRODUCT_COST.NewPRODUCT_COSTRow();
                        productCostRow.COST = row.COST;
                        productCostRow.COST_PROTOCOL_ID = _costPRow.ID;
                        productCostRow.PID = _costPRow.PID;
                        productCostRow.PRODUCT_UNIT_ID = unitsRow.ID;
                        dataSetFSO1.PRODUCT_COST.AddPRODUCT_COSTRow(productCostRow);
                    }

                }
                else if (dCount < 0)
                {
                    //Заполняем в лист цены по текущей строке
                    List<DataSetFSO.PRODUCT_COSTRow> listCosts = new List<DataSetFSO.PRODUCT_COSTRow>();
                    foreach (DataSetFSO.PRODUCT_COSTRow tmpCostPrRow in (producT_COSTTableAdapter1.GetDataForCostPrByProductsNameCPStage(row.CP_STAGE_ID, _costPRow.PID, _costPRow.ID, row.NAME)).Rows)
                    {
                        listCosts.Add(dataSetFSO1.PRODUCT_COST.FindByID(tmpCostPrRow.ID));
                    }

                    int count = listCosts.Count;
                    //Удалить можно только те цены на продукты, на которые не были выставлены платежи, счета и счет-фактуры, служ записки и цех накладные
                    VIEW_SEARCH_P_U_FOR_FORMSTableAdapter ta = new VIEW_SEARCH_P_U_FOR_FORMSTableAdapter();
                    DataSetFSO.VIEW_SEARCH_P_U_FOR_FORMSRow prUnitRow;
                    //int delCount = -dCount;
                    int i = count-1;

                    while (dCount < 0 && i >= 0)
                    {
                        //Получаем строку товара со всеми нужными нам связями
                        prUnitRow = ta.GetDataByPrUnitID(listCosts[i].PRODUCT_UNIT_ID).FindByID(listCosts[i].PRODUCT_UNIT_ID);
                        //Если есть хоть 1 связь, то переходим к проверке др элемента, Иначе удаляем текущий элемент
                        bool t = (bool)ta.f_Is_PU_Has_Inv_Pay(prUnitRow.ID);
                        if ( !((bool) ta.f_Is_PU_Has_Inv_Pay(prUnitRow.ID)) && prUnitRow.IsVAT_INVOICE_IDNull() && prUnitRow.IsDIRECT_NUMBER_IDNull() && prUnitRow.IsGUILD_BILL_NUMBER_IDNull())
                        {
                            listCosts[i].Delete();
                            dCount++;
                        }
                        i--;
                    }
                    notDelCount -= dCount;
                }
                //Изменилась только цена товаров
                else if (dCount == 0 && isModified)
                {
                    //Заполняем в лист цены по текущей строке
                    foreach (DataSetFSO.PRODUCT_COSTRow tmpCostPrRow in (producT_COSTTableAdapter1.GetDataForCostPrByProductsNameCPStage(row.CP_STAGE_ID, _costPRow.PID, _costPRow.ID, row.NAME)).Rows)
                    {
                        dataSetFSO1.PRODUCT_COST.FindByID(tmpCostPrRow.ID).COST = cost;
                    }

                }

            }

            if (notDelCount > 0)
            {
                MessageBox.Show("Невозможно удалить "+notDelCount+" товаров из протокола!");
                returnValue = -1;
            }

            cosT_PROTOCOLTableAdapter1.Update(_costPRow);
            producT_COSTTableAdapter1.Update(dataSetFSO1.PRODUCT_COST);

            RefreshForm();

            return returnValue;
        }

        public int RefreshForm()
        {
            //Очищаем все таблицы
            foreach (DataTable table in dataSetFSO1.Tables)
            {
                if (!(table is DataSetFSO.COST_PROTOCOLDataTable))
                {
                    table.Clear();
                }
            }

            //Валюта
            nsI_CURRENCYTableAdapter1.Fill(dataSetFSO1.NSI_CURRENCY);
            radDropDownListNsiCurrency.Items.Clear();
            foreach (DataSetFSO.NSI_CURRENCYRow row in dataSetFSO1.NSI_CURRENCY.Rows)
            {
                radDropDownListNsiCurrency.Items.Add(new RadListDataItem() { Text = row.SHORT_NAME, Value = row.ID });
            }
            BindControls();
            //Перезаполняем продукты
            aggR_PRODUCT_COSTTableAdapter1.FillByCostPrID(dataSetFSO1.AGGR_PRODUCT_COST, _costPRow.ID);
            InitializeProductUnitsGrid();
            return 0;
        }

        public string FormName
        {
            get
            {
                string returnString = "Cost_Protocol_";

                if (_costPRow.ID<0)
                {
                    returnString = returnString + DateTime.Now;
                }
                else
                {
                    returnString = returnString + _costPRow.NUMBER;
                }

                return returnString;
            }
        }

        private void FormCostProtocol_Load(object sender, EventArgs e)
        {
            //this.InitializeProductUnitsGrid();
            radGridViewItems.ShowGroupPanel = false;
            this.RefreshForm();
        }

        private void radCheckBoxIsAgree_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            //MessageBox.Show(_costPRow.IS_AGREED.ToString());
            bool controlEnable = !radCheckBoxIsAgree.Checked;
            this.EnabledControls(controlEnable);
        }

        private void radButtonAdd_Click(object sender, EventArgs e)
        {
            DialogFormSelectObject dialogForm = new DialogFormSelectObject(ObjctTypeEnum.PRODUCT_UNIT_FOR_COST_PROTOCOL, _costPRow.PID);
            if(dialogForm.ShowDialog() == DialogResult.OK)
            {
                foreach (GridViewRowInfo rowInf in dialogForm.SelectedRows)
                {
                    DataRowView drv = (DataRowView)rowInf.DataBoundItem;
                    if (drv != null && drv.Row is DataSetFSO.VIEW_SEARCH_PU_FOR_COST_PROTOCOLRow)
                    {
                        DataSetFSO.VIEW_SEARCH_PU_FOR_COST_PROTOCOLRow searchRow = drv.Row as DataSetFSO.VIEW_SEARCH_PU_FOR_COST_PROTOCOLRow;
                       
                        DataSetFSO.AGGR_PRODUCT_COSTRow rowOrig = dataSetFSO1.AGGR_PRODUCT_COST.NewAGGR_PRODUCT_COSTRow();
                        
                        //rowOrig.INVOICE_INRow = _rowInvoiceIn;
                        rowOrig.NAME = searchRow.NAME;
                        rowOrig.COUNT = searchRow.COUNT_TMP;
                        rowOrig.COST = 0;
                        rowOrig.NSI_METER_NAME = searchRow.METER;
                        rowOrig.CP_STAGE_NUM = searchRow.CAL_P_NUMBER;
                        //rowOrig.CP_STAGE_NAME = searchRow.CAL_P_NAME;
                        rowOrig.CP_STAGE_SDATE = searchRow.CAL_P_START_DATE;
                        rowOrig.CP_STAGE_EDATE = searchRow.CAL_P_END_DATE;
                        rowOrig.CP_STAGE_ID = searchRow.CP_STAGE_ID;

                        try
                        {
                            dataSetFSO1.AGGR_PRODUCT_COST.AddAGGR_PRODUCT_COSTRow(rowOrig);
                        }
                        catch (ConstraintException)
                        { 
                            //Ошибка вызывается если продукция с таким наименованием и с этого этапа уже была добавлена к ПСЦ, тогда добавляем количесво и все
                            DataSetFSO.AGGR_PRODUCT_COSTRow tmpRow = (from row in dataSetFSO1.AGGR_PRODUCT_COST where (row.CP_STAGE_ID == searchRow.CP_STAGE_ID && row.NAME == searchRow.NAME) select row).First();
                            if (tmpRow.COUNT <= 0)
                            {
                                MessageBox.Show("Необходимо сохранить протокол, прежде, чем заново добавить товар данного наименования!", "Сохраните изменения!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                tmpRow.COUNT++;
                            }
                        }
                        
                    }
                }
            }
        }

        private void radButtonDelete_Click(object sender, EventArgs e)
        {

            GridViewRowInfo rowInfo = radGridViewItems.SelectedRows.First();

            DataRowView drv = (DataRowView)rowInfo.DataBoundItem;
            if (drv != null && drv.Row is DataSetFSO.AGGR_PRODUCT_COSTRow)
            {
                (drv.Row as DataSetFSO.AGGR_PRODUCT_COSTRow).COUNT = 0;
                rowInfo.IsVisible = false;
            }

        }

        private void FormCostProtocol_FormClosing(object sender, FormClosingEventArgs e)
        {
			if (!AllowSave)
				return;
            if (_costPRow.RowState != DataRowState.Deleted && _costPRow.RowState != DataRowState.Detached && (_costPRow.RowState == DataRowState.Added || _costPRow.RowState == DataRowState.Modified || (dataSetFSO1.AGGR_PRODUCT_COST.GetChanges()) != null))
            {
                DialogResult result = MessageBox.Show(this, "Были внесены изменения. Сохранить?", "Сохранить изменения?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                if (result == DialogResult.Yes)
                {
                    int SaveResult = this.Save();

                    if (SaveResult == -1)
                    {
                        e.Cancel = true;
                    }
                }
                else if (result == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
                else
                {
                    dataSetFSO1.RejectChanges();
                }

            }
        }

        private void radGridViewItems_GroupByChanged(object sender, GridViewCollectionChangedEventArgs e)
        {
            //int i = 0;
            //foreach (Object row in e.NewItems)
            //{
            //    i++;
            //}

           // MessageBox.Show(i.ToString());
        }

    }
}
